package org.jeecg.modules.filemanage.base.service.impl;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.jeecg.common.es.JeecgElasticsearchTemplate;
import org.jeecg.common.util.DateUtils;
import org.jeecg.common.util.UUIDGenerator;
import org.jeecg.modules.filemanage.base.entity.FmFileDetailsHistory;
import org.jeecg.modules.filemanage.base.entity.FmFileDetailsInfo;
import org.jeecg.modules.filemanage.base.entity.FmFileDirInfo;
import org.jeecg.modules.filemanage.base.service.IFmFileDetailsHistoryService;
import org.jeecg.modules.filemanage.base.service.IFmFileDetailsInfoService;
import org.jeecg.modules.filemanage.base.service.IFmFileDirInfoService;
import org.jeecg.modules.filemanage.base.service.IFileTransManageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.beans.BeanCopier;
import org.springframework.cglib.core.Converter;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * @Description: 文件上传下载事务处理实现类
 * @Author: chris
 * @Date:   2020-08-21
 * @Version: V1.0
 */
@Service
public class FileTransManageServiceImpl implements IFileTransManageService {
    @Autowired
    private IFmFileDirInfoService iFileDirInfoService;
    @Autowired
    private IFmFileDetailsInfoService iFileDetailsInfoService;
    @Autowired
    private IFmFileDetailsHistoryService iFileDetailsHistoryService;
    @Autowired
    private JeecgElasticsearchTemplate jeecgElasticsearchTemplate;
    private static final Map<String, BeanCopier> BEAN_COPIERS = new ConcurrentHashMap<>();

    @Transactional
    public boolean add(Map<String,Object> map){
        boolean savedir=false ,savedts=false ,savehis=false ,savees = false;
        FmFileDirInfo fileDirInfo = JSON.parseObject(JSONObject.toJSONString(map.get("obj")),FmFileDirInfo.class);
        FmFileDetailsInfo fileDetailsInfo = JSON.parseObject(JSONObject.toJSONString(map.get("obb")),FmFileDetailsInfo.class);
        FmFileDetailsHistory fileDetailsHistory = new FmFileDetailsHistory();
        if(fileDirInfo == null ||fileDetailsInfo ==null)    return false;

        //存业务表信息
        String fileid = fileDirInfo.getFileid();
        Date nowdate = DateUtils.getDate();
        if(fileDirInfo.getId()==null||fileDirInfo.getId().isEmpty())
            fileDirInfo.setId(UUIDGenerator.generate());
        fileDirInfo.setFileid(fileid);
        fileDirInfo.setVersionNo(1.0);
        fileDirInfo.setCreateTime(nowdate);
        if(fileDetailsInfo.getId()==null||fileDetailsInfo.getId().isEmpty())
            fileDetailsInfo.setId(UUIDGenerator.generate());
        fileDetailsInfo.setFileid(fileid);
        if(fileDetailsInfo.getFilePath()==null||fileDetailsInfo.getFilePath().isEmpty())
            fileDetailsInfo.setFilePath(fileDetailsInfo.getModelName()+"//"+fileDetailsInfo.getFileMixName());
        fileDetailsInfo.setCreateTime(nowdate);
        //单独构建文件历史记录表
        //fileDetailsHistory.setId(UUIDGenerator.generate());
        BeanCopier beanCopier;
        String key = genKey(fileDetailsInfo.getClass(), fileDetailsHistory.getClass());
        if (!BEAN_COPIERS.containsKey(key)) {
            beanCopier = BeanCopier.create(FmFileDetailsInfo.class, FmFileDetailsHistory.class, false);
            BEAN_COPIERS.put(key, beanCopier);
        }else{
            beanCopier = BEAN_COPIERS.get(key);
        }
        beanCopier.copy(fileDetailsInfo,fileDetailsHistory,(Converter) null);
        fileDetailsHistory.setFileid(fileid);
        fileDetailsHistory.setCreateTime(nowdate);
        fileDetailsHistory.setOpt(0);
        fileDetailsHistory.setVersionNo(fileDirInfo.getVersionNo());

        savedir = iFileDirInfoService.save(fileDirInfo);
        savedts = iFileDetailsInfoService.save(fileDetailsInfo);
        savehis = iFileDetailsHistoryService.save(fileDetailsHistory);

        //文件数据存储到es

        savees = saveOrUpdateEs(fileid,JSONObject.parseObject(JSONObject.toJSONString(fileDetailsInfo)),fileDetailsInfo.getModelName(),"doc_cn_index");

        if(!savedir||!savedts||!savehis ||!savees) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return false;
        }
        else
            return true;
    }

    public boolean saveOrUpdateEs(String id,JSONObject data,String modelName,String indexName){
      return  jeecgElasticsearchTemplate.save(indexName,modelName,id,data);
    }

    private boolean deleteEs(String id,String modelName,String indexName){
        return  jeecgElasticsearchTemplate.delete(indexName,modelName,id);
    }

    private static String genKey(Class<?> srcClazz, Class<?> destClazz) {
                 return srcClazz.getName() + destClazz.getName();
    }

    @Transactional
    public boolean edit(Map<String,Object> map){
        boolean savedir=false ,savedts=false ,savehis=false ,savees = false;
        FmFileDirInfo fileDirInfo = JSON.parseObject(JSONObject.toJSONString(map.get("obj")),FmFileDirInfo.class);
        FmFileDetailsInfo fileDetailsInfo = JSON.parseObject(JSONObject.toJSONString(map.get("obb")),FmFileDetailsInfo.class);
        FmFileDetailsHistory fileDetailsHistory = new FmFileDetailsHistory();


        //更新业务表信息
        Date nowdate = DateUtils.getDate();
        fileDirInfo.setUpdateTime(nowdate);
        fileDirInfo.setVersionNo(fileDirInfo.getVersionNo()+1);
        fileDetailsInfo.setUpdateTime(nowdate);
        if(fileDetailsInfo.getFilePath().isEmpty())
            fileDetailsInfo.setFilePath(fileDetailsInfo.getModelName()+"//"+fileDetailsInfo.getFileMixName());
        if(fileDirInfo.getId().isEmpty())
        {
            //如果参数没有取到FileDirInfo表的id  避免编辑失败  通过fileid去自主寻找一次id
            Map<String,Object> param = new HashMap<>();
            param.put("fileid",fileDirInfo.getFileid());
            List<FmFileDirInfo> fileDirInfoTemp = this.iFileDirInfoService.listByMap(param);
            if(fileDirInfoTemp.size()>0)
                fileDirInfo.setId(fileDirInfoTemp.get(0).getId());
        }
        //单独构建文件历史记录表
        //fileDetailsHistory.setId(UUIDGenerator.generate());
        BeanCopier beanCopier = BeanCopier.create(FmFileDetailsInfo.class,FmFileDetailsHistory.class, false);
        beanCopier.copy(fileDetailsInfo,fileDetailsHistory,null);
        fileDetailsHistory.setFileid(fileDirInfo.getFileid());
        fileDetailsHistory.setCreateTime(nowdate);
        fileDetailsHistory.setOpt(2);
        fileDetailsHistory.setVersionNo(fileDirInfo.getVersionNo());


        savedir = iFileDirInfoService.updateById(fileDirInfo);
        savedts =  iFileDetailsInfoService.updateById(fileDetailsInfo);
        savehis = iFileDetailsHistoryService.save(fileDetailsHistory);

        //更新es
        savees = saveOrUpdateEs(fileDirInfo.getFileid(),JSONObject.parseObject(JSONObject.toJSONString(fileDetailsInfo)),fileDetailsInfo.getModelName(),"doc_cn_index");

        if(!savedir||!savedts||!savehis ||!savees) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return false;
        }
        else
            return true;

    }

    @Transactional(propagation= Propagation.NOT_SUPPORTED)
    public boolean delete(String ids){
        List<String> idlist = Arrays.asList(ids.split(","));
        //取出id对应的数据明细,这里取的是文件明细表，版本表需要查询
        StringBuilder idString = new StringBuilder();
        FmFileDetailsInfo fileDetailsInfo;
        for(String s : idlist){
            fileDetailsInfo = new FmFileDetailsInfo();
            fileDetailsInfo = iFileDetailsInfoService.getById(s);
            idString.append("'").append(fileDetailsInfo.getFileid()).append("',");
            //删除es信息
            deleteEs(fileDetailsInfo.getFileid(),fileDetailsInfo.getModelName(),"doc_cn_index");
        }
        String fileid = idString.substring(0,idString.length()-1).toString();
        //获取版本表信息
        List<FmFileDirInfo> fdilist =new ArrayList<FmFileDirInfo>();
        fdilist =iFileDirInfoService.getFileDirByFileid(fileid);
        List<String> fdiids = fdilist.stream().map(FmFileDirInfo::getId).collect(Collectors.toList());

        boolean savedir=false ,savedts=false ,savehis=false ,savees = false;

        List<FmFileDetailsHistory> fileDetailsHistoryList = new ArrayList<FmFileDetailsHistory>();
        FmFileDetailsHistory fileDetailsHistory ;
        Date nowdate = DateUtils.getDate();
        List<FmFileDetailsInfo> fdtlist = iFileDetailsInfoService.listByIds(idlist);
        BeanCopier beanCopier = BeanCopier.create(FmFileDetailsInfo.class,FmFileDetailsHistory.class, false);
        for(FmFileDetailsInfo f: fdtlist){
            //查找对应版本信息
            double version_no = fdilist.stream().filter(s->s.getFileid().equalsIgnoreCase(f.getFileid())).collect(Collectors.toList()).get(0).getVersionNo();
         //给每条删除的文件信息，增加版本信息记录
            fileDetailsHistory = new FmFileDetailsHistory();
            beanCopier.copy(f,fileDetailsHistory,null);
            fileDetailsHistory.setId(UUIDGenerator.generate());
            fileDetailsHistory.setCreateTime(nowdate);
            fileDetailsHistory.setOpt(3);
            fileDetailsHistory.setVersionNo(version_no+1);
            fileDetailsHistoryList.add(fileDetailsHistory);
        }

        savehis = iFileDetailsHistoryService.saveBatch(fileDetailsHistoryList);
        savedts = iFileDetailsInfoService.removeByIds(idlist);
        savedir = iFileDirInfoService.removeByIds(fdiids);


        if(!savedir||!savedts||!savehis ){
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return false;
        }
        else
            return true;
    }


    //批量添加需要事先拼装好fileid
    @Transactional
    public boolean batchadd(Map<String,Object> map){
        boolean savedir=false ,savedts=false ,savehis=false ;
        List<FmFileDirInfo> fileDirInfo = (List<FmFileDirInfo>) map.get("obj");
        List<FmFileDetailsInfo> fileDetailsInfo = (List<FmFileDetailsInfo>) map.get("obb");
        List<FmFileDetailsHistory> Listhis =new ArrayList<>();
        FmFileDetailsHistory fileDetailsHistory = null;
        BeanCopier beanCopier = BeanCopier.create(FmFileDetailsInfo.class,FmFileDetailsHistory.class, false);
        if(fileDirInfo == null ||fileDetailsInfo ==null)    return false;

        for(FmFileDetailsInfo f : fileDetailsInfo) {
            f.setId(UUIDGenerator.generate());
            fileDetailsHistory = new FmFileDetailsHistory();
            //单独构建文件历史记录表
            //fileDetailsHistory.setId(UUIDGenerator.generate());
            beanCopier.copy(f,fileDetailsHistory,null);
            fileDetailsHistory.setCreateTime(DateUtils.getDate());
            fileDetailsHistory.setOpt(0);
            fileDetailsHistory.setVersionNo(1.0);
            Listhis.add(fileDetailsHistory);
            saveOrUpdateEs(f.getFileid(),JSONObject.parseObject(JSONObject.toJSONString(f)),f.getModelName(),"doc_cn_index");
        }

        savehis = iFileDetailsHistoryService.saveBatch(Listhis);
        savedts = iFileDetailsInfoService.saveBatch(fileDetailsInfo);
        savedir = iFileDirInfoService.saveBatch(fileDirInfo);

        if(!savedir||!savedts||!savehis) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return false;
        }
        else
            return true;
    }
}
